import Diccionario
import Maybe
import List

--Este módulo sirve para utilizar el diccionario sin acceder a su estructura interna. Pueden agregar otras funciones o casos de prueba.

{- Función a implementar. -}


-- Ejercicio 10

-- La función busquedaDelTesoro genera la lista infinita de sucesivas búsquedas de pistas a partir de la pista inicial (con iterate), y luego la recorre en búsqueda del tesoro.
-- En caso de no encontrar el tesoro, retornará Nothing.
-- En caso de generarse un ciclo dentro de la búsqueda, la función se cuelga.
busquedaDelTesoro :: Eq a => a -> (a -> Bool) -> Diccionario a a -> Maybe a
busquedaDelTesoro pista_inicial es_tesoro dicc = foldr1 (encontrar_pista es_tesoro) pistas
	where
		pistas = iterate (pasoDeBusqueda dicc) (Just pista_inicial)

-- La función encontrar_pista verifica si la pista que es pasada como argumento es el tesoro buscado.
-- Será utilizada como argumento de foldr1 para recorrer la lista hasta encontrar la pista que sea el tesoro.
-- En caso de que la pista actual sea Nothing, retorna Nothing para evitar seguir recorriendo la lista (que es infinita).
encontrar_pista :: Eq pista => (pista -> Bool) -> Maybe pista -> Maybe pista -> Maybe pista
encontrar_pista es_tesoro Nothing _ = Nothing
encontrar_pista es_tesoro (Just pista_actual) pista_siguiente
													|(es_tesoro pista_actual) = (Just pista_actual)
													|otherwise				  = pista_siguiente

-- La función pasoDeBusqueda ejecuta la búsqueda de una pista y retorna la siguiente pista, obtenida a partir de la última.
-- En caso de que la pista sea Nothing, devuelve Nothing por el funcionamiento del operador bind.
pasoDeBusqueda :: Eq pista => Diccionario pista pista -> Maybe pista -> Maybe pista
pasoDeBusqueda dicc pista_actual = pista_actual >>= flip obtener dicc



{- Diccionarios de prueba: -}

dicc1::Diccionario Int String
dicc1 = definirVarias [(0,"Hola"),(-10,"Chau"),(15,"Felicidades"),(2,"etc."),(9,"a")] (vacio (<))

dicc2::Diccionario String String
dicc2 = definirVarias [("inicio","casa"),("auto","flores"),("calle","auto"),("casa","escalera"),("ropero","alfajor"),("escalera","ropero")] (vacio (<))

dicc3::Diccionario Int String
dicc3 = definirVarias [(0,"Hola"),(-10,"Chau"),(15,"Felicidades"),(2,"etc."),(9,"a")] (vacio (\x y->x `mod` 5 < y `mod` 5))

--Ejemplo: busquedaDelTesoro "inicio" ((=='a').head) dicc2 = Just "alfajor"